#include "StdAfx.h"
#include "resource.h"

#include "waconsts.h"
#include "DataStore.h"
#include "eeg_exceptions.h"

using namespace std;

DataStore *DataStore::instance = 0;
DataStore::DataStore(void)
{
	current=-1;
	samplingRate=0;
	refType=DATA_REF_TYPE_NONE;
	int i=-1;
	refChannel[0]=0;
	refChannel[1]=0;
	refChannel[2]=0;
}

DataStore::~DataStore(void)
{
	CleanAll();
}

/*const Channel& DataStore::GetChannel(int n) const
{
	//TODO: insert return statement here
	return data[n];
}*/

int DataStore::AddChannel(int eid, size_t rs)
{
	data.push_back(new Channel(eid, rs));
	switch(eid){
		case A1:
			refChannel[0]=data[data.size()-1];break;
		case A2:
			refChannel[1]=data[data.size()-1];break;
		case CZ:
			refChannel[2]=data[data.size()-1];break;
		default:
			break;
	}
	current++;
	return current;
}

int DataStore::EndChannel(void)
{
	return data[current]->data.size();
}


void DataStore::CleanAll(void)
{
	for(size_t i=0;i<data.size();i++)
		delete data[i];
	data.clear();
	current=-1;
	samplingRate=-1;
	refType=DATA_REF_TYPE_NONE;
}

int DataStore::GetChannelCount(void) const 
{
	return data.size();
}

void DataStore::SetChannelName(LPCTSTR name)
{
	if( current == -1)
		throw EEG_Exceptions(3, _T("DS: Invail Current Channel"));
	wcscpy(data[current]->electrode.name,name);
}

void DataStore::SetRef(int refType)
{
	/*int i=0;
	if(refChannel[0]==0 || refChannel[1]==0 || refChannel[2]==0)
	{
	   refChannel[0]=&data[(i=GetElectrode(A1))==-1? 0:i];
	   refChannel[1]=&data[(i=GetElectrode(A2))==-1? 0:i];
	   refChannel[2]=&data[(i=GetElectrode(CZ))==-1? 0:i];
	}
	if(refType==0 && refChannel[0]!=0 && refChannel[1]!=0)
	  {  
		  this->refType=refType;
	      return true;
	  }
	else if(refType==1 && refChannel[3]!=0)
	  {  
		  this->refType=refType;
		  return true;
	  }
	  else return false;
		//Its host in CWaveAnalysisCtrl shall invoke UpdateEverthing()*/
	bool isErr = false;
	switch(refType){
		case DATA_REF_TYPE_NONE:
			break;
		case DATA_REF_TYPE_A:
			if( (refChannel[0]==0) || (refChannel[1]==0 ) )
				isErr=true;
			break;
		case DATA_REF_TYPE_C:
			if( refChannel[2]==0)
				isErr=true;
			break;
		default:
			throw EEG_Exceptions(2, _T("DS:  Unknown Ref. Type"));
	}
	if(isErr)
		throw EEG_Exceptions(1, _T("DS:  Ref. Channels' data is NOT ready"));
	this->refType=refType;	//Its host in CWaveAnalysisCtrl shall invoke UpdateEverthing()
}

// Get the index of the channel from a given electrodeID. Return -1 if the that electrode is not available.
int DataStore::GetElectrodeIndex(int electrodeID) const
{
	for(int i=0;i<GetChannelCount();i++)
	{  
		int eid = data[i]->electrodeID;
		if(eid ==electrodeID)
		   return i;
	}
	return -1;
}


const Channel* DataStore::GetChannelByEID(unsigned int eid) const
{
	//TODO: insert return statement here
	for(size_t i=0;i<data.size();i++){
		if(data[i]->electrodeID==eid)
			return  data[i];
	}
	return 0;
}

LPCTSTR DataStore::GetRefTypeString() const {
	switch(refType){
		case DATA_REF_TYPE_NONE:
			return _T("NONE");
		case DATA_REF_TYPE_A:
			return _T("Aav");
		case DATA_REF_TYPE_C:
			return _T("C");
		default:
			return _T("UNKNOWN");
	}
}

void DataStore::SetElectrodePos(double x, double y, int electrodeID){
	int index = -1;
	if(electrodeID==-1)
		index = current;
	else
		index = GetElectrodeIndex(electrodeID);

	if(index == -1) throw EEG_Exceptions(1, _T("DS:  Invalid EID "));
	data[index]->electrode.xpos = x;
	data[index]->electrode.ypos = y;
}